package com.dspobox;

import java.io.*;
import java.util.*;

public class Dict {

	public static class DicEntry {

		String pat, word, context;

		public DicEntry(String word, String pat, String context) {
			this.word = word;
			this.pat = pat;
			this.context = context;
		}

		public boolean equals(String word, String pat, String context) {
			return this.word.equals(word) && this.pat.equals(pat)
					&& (this.context != null && this.context.equals(context));
		}

		public boolean equalsIgnoreContext(String word, String pat) {
			return this.word.equals(word) && this.pat.equals(pat)
					&& (this.context == null || this.context.isEmpty());
		}
	}

	private String name;
	private List<DicEntry> entries;

	public List<DicEntry> getEntries() {
		return entries;
	}

	public Dict(String name) {
		this.name = name;
		entries = new ArrayList<DicEntry>();
	}

	private static String getPath(String base) {
		File file = new File(System.getProperty("user.home") + File.separator
				+ base);
		return file.getAbsolutePath();
	}

	public DicEntry regent(String word, String pat, String context) {
		DicEntry e = new DicEntry(word, pat, context);
		entries.add(e);
		return e;
	}

	public DicEntry getent(int nth) {
		return entries.get(nth);
	}

	public void delent(int nth) {
		entries.remove(nth);
	}

	private DicEntry findIgnoreContext(String word, String pat) {
		for (DicEntry e : entries)
			if (e.equalsIgnoreContext(word, pat))
				return e;
		
		return null;
	}
	
	private DicEntry find(String word, String pat, String context) {
		for (DicEntry e : entries)
			if (e.equals(word, pat, context))
				return e;
		
		return null;
	}
	
	public boolean regword(String word, String pat, String context) {
		if (word == null || word.isEmpty() || pat == null || pat.isEmpty())
			return false;

		learnWord(word, pat, context);

		if (context != null && !context.isEmpty())
			learnSentence(word, pat, context);

		return true;
	}

	private void learnSentence(String word, String pat, String context) {
		DicEntry e = find(word, pat, context);
		if (e == null)
			e = regent(word, pat, context);

		touch(e);
	}

	private void learnWord(String word, String pat, String context) {
		DicEntry e = findIgnoreContext(word, pat);
		if (e == null)
			e = regent(word, pat, context);

		touch(e);
	}

	private void touch(DicEntry matched) {
		entries.remove(matched);
		entries.add(0, matched);
	}

	public boolean delword(String word) {
		for (Iterator<Dict.DicEntry> it = entries.iterator(); it.hasNext();)
			if (word.equals(it.next().word))
				it.remove();

		return true;
	}

	public void load() throws IOException {
		BufferedReader r = new BufferedReader(new FileReader(getPath(name)));

		String line = null;
		while ((line = r.readLine()) != null) {
			if (line.startsWith("#"))
				continue;
			String[] v = line.split("[ \t]");
			if (v.length == 3)
				regent(v[1], v[0], v[2]);
			else if (v.length == 2)
				regent(v[1], v[0], null);
		}
		r.close();
	}

	public void save() throws IOException {
		save(getPath(name));
	}

	private void save(String path) throws IOException {
		BufferedWriter w = new BufferedWriter(new FileWriter(path));
		for (DicEntry e : entries) {
			w.append(e.word).append('\t').append(e.pat);
			if (e.context != null)
				w.append('\t').append(e.context);
			w.append('\n');
		}
		w.close();
	}
	
	public void saveAs(String s) throws IOException {
		save(getPath(s));
	}

}